package handlers

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"

	"github.com/samaa/photosalesplus/backend/internal/services"
)

type OrderHandler struct {
	service services.OrderService
}

func NewOrderHandler(service services.OrderService) *OrderHandler {
	return &OrderHandler{service: service}
}

type orderItemRequest struct {
	ProductID uint `json:"product_id" binding:"required"`
	Quantity  int  `json:"quantity"`
}

type createOrderRequest struct {
	Contact string             `json:"contact"`
	Items   []orderItemRequest `json:"items" binding:"required,min=1"`
}

func (h *OrderHandler) Create(c *gin.Context) {
	userID, ok := currentUserID(c)
	if !ok {
		c.JSON(http.StatusUnauthorized, APIResponse{Error: "未授权"})
		return
	}

	var req createOrderRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{Error: err.Error()})
		return
	}

	items := convertOrderItems(req.Items)
	if len(items) == 0 {
		c.JSON(http.StatusBadRequest, APIResponse{Error: "商品列表不能为空"})
		return
	}

	order, err := h.service.Create(c.Request.Context(), userID, req.Contact, items)
	if err != nil {
		respondError(c, http.StatusInternalServerError, err)
		return
	}

	respondCreated(c, order)
}

func (h *OrderHandler) Preview(c *gin.Context) {
	userID, ok := currentUserID(c)
	if !ok {
		c.JSON(http.StatusUnauthorized, APIResponse{Error: "未授权"})
		return
	}

	var req struct {
		Items []orderItemRequest `json:"items" binding:"required,min=1"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{Error: err.Error()})
		return
	}

	items := convertOrderItems(req.Items)
	if len(items) == 0 {
		c.JSON(http.StatusBadRequest, APIResponse{Error: "商品列表不能为空"})
		return
	}

	preview, err := h.service.Preview(c.Request.Context(), userID, items)
	if err != nil {
		respondError(c, http.StatusInternalServerError, err)
		return
	}

	respondSuccess(c, preview, gin.H{
		"hint":       "金额以实时价格计算，支持微信支付与支付宝支付。",
		"channels":   []string{"wechat", "alipay"},
		"can_pay":    true,
		"item_count": len(preview.Items),
	})
}

func (h *OrderHandler) List(c *gin.Context) {
	userID, ok := currentUserID(c)
	if !ok {
		c.JSON(http.StatusUnauthorized, APIResponse{Error: "未授权"})
		return
	}

	orders, err := h.service.ListForUser(c.Request.Context(), userID)
	if err != nil {
		respondError(c, http.StatusInternalServerError, err)
		return
	}
	respondSuccess(c, orders, nil)
}

func (h *OrderHandler) Purchases(c *gin.Context) {
	userID, ok := currentUserID(c)
	if !ok {
		c.JSON(http.StatusUnauthorized, APIResponse{Error: "未授权"})
		return
	}

	ids, err := h.service.PurchasedProductIDs(c.Request.Context(), userID)
	if err != nil {
		respondError(c, http.StatusInternalServerError, err)
		return
	}
	respondSuccess(c, ids, nil)
}

func (h *OrderHandler) CustomerLeaderboard(c *gin.Context) {
	page := 1
	limit := 20
	if raw := c.Query("page"); raw != "" {
		if parsed, err := strconv.Atoi(raw); err == nil && parsed > 0 {
			page = parsed
		}
	}
	if raw := c.Query("limit"); raw != "" {
		if parsed, err := strconv.Atoi(raw); err == nil && parsed > 0 {
			limit = parsed
		}
	}

	leaderboard, hasMore, err := h.service.CustomerLeaderboard(c.Request.Context(), page, limit)
	if err != nil {
		respondError(c, http.StatusInternalServerError, err)
		return
	}

	meta := gin.H{
		"hint":     "榜单基于真实订单累计消费金额（仅统计已完成支付订单），实时更新。",
		"count":    len(leaderboard),
		"page":     page,
		"limit":    limit,
		"has_more": hasMore,
	}

	respondSuccess(c, leaderboard, meta)
}

func (h *OrderHandler) Overview(c *gin.Context) {
	overview, err := h.service.MerchantOverview(c.Request.Context())
	if err != nil {
		respondError(c, http.StatusInternalServerError, err)
		return
	}
	respondSuccess(c, overview, nil)
}

func currentUserID(c *gin.Context) (uint, bool) {
	val, exists := c.Get("user_id")
	if !exists {
		return 0, false
	}
	id, ok := val.(uint)
	if !ok || id == 0 {
		return 0, false
	}
	return id, true
}

func convertOrderItems(items []orderItemRequest) []services.OrderItemInput {
	result := make([]services.OrderItemInput, 0, len(items))
	for _, item := range items {
		if item.ProductID == 0 {
			continue
		}
		qty := item.Quantity
		if qty <= 0 {
			qty = 1
		}
		result = append(result, services.OrderItemInput{
			ProductID: item.ProductID,
			Quantity:  qty,
		})
	}
	return result
}
